const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const TerserPlugin = require('terser-webpack-plugin');
// const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
const IgnoreEmitPlugin = require('ignore-emit-webpack-plugin');
const popVars = require('./scripts/pop-vars');

function processWebpackThemeConfig(themeConfig, theme, vars) {
  themeConfig.forEach((config) => {
    Object.keys(config.entry).forEach((entryName) => {
      config.entry[entryName.replace('ruxd', `ruxd.${theme}`)] = config.entry[entryName];
      delete config.entry[entryName];
    });

    // apply ${theme} less variables
    config.module.rules.forEach((rule) => {
      // filter less rule
      if (rule.test instanceof RegExp && rule.test.test('.less')) {
        const lessRule = rule.use[rule.use.length - 1];
        if (lessRule.options.lessOptions) {
          lessRule.options.lessOptions.modifyVars = vars;
        } else {
          lessRule.options.modifyVars = vars;
        }
      }
    });

    const themeReg = new RegExp(`${theme}(.min)?\\.js(\\.map)?$`);
    // ignore emit ${theme} entry js & js.map file
    config.plugins.push(new IgnoreEmitPlugin(themeReg));
  });
}

function resolve(moduleName) {
  return require.resolve(moduleName);
}

function babelConfig() {
  const plugins = [
    [
      resolve('@babel/plugin-transform-typescript'),
      {
        isTSX: true,
      },
    ],
    resolve('@babel/plugin-proposal-object-rest-spread'),
    [
      resolve('@babel/plugin-proposal-decorators'),
      {
        legacy: true,
      },
    ],
    resolve('@babel/plugin-proposal-class-properties'),
  ];
  return {
    presets: [
      resolve('@babel/preset-react'),
      [
        resolve('@babel/preset-env'),
        {
          targets: {
            browsers: ['last 2 versions', 'Firefox ESR', '> 1%', 'ie >= 11'],
          },
        },
      ],
    ],
    plugins,
  };
}

function webpackConfig() {
  return [
    {
      entry: {
        ruxd: './src/index.ts',
        'ruxd.min': './src/index.ts',
      },
      output: {
        filename: '[name].js',
        library: 'ruxd',
        libraryExport: 'default',
        path: path.resolve(__dirname, 'dist'),
        globalObject: 'this',
      },
      mode: 'production',
      resolve: {
        extensions: ['.ts', '.tsx', '.json', '.css', '.js', '.less', '.jsx'],
      },
      optimization: {
        minimize: true,
        minimizer: [
          new TerserPlugin({
            include: /\.min\.js$/,
          }),
          new CssMinimizerPlugin({
            include: /\.min\.js$/,
          }),
        ],
      },
      module: {
        rules: [
          {
            test: /\.(png|jpg|gif|svg)$/i,
            type: 'asset',
          },
          {
            test: /\.jsx?$/,
            // exclude: /(node_modules|bower_components)/,
            use: {
              loader: 'babel-loader',
              options: babelConfig(),
              // options: {
              //   presets: ['@umijs/babel-preset-umi/app'],
              //   plugins: [require('./scripts/replaceLib')],
              // },
            },
          },
          {
            test: /\.tsx?$/,
            exclude: /(node_modules|bower_components)/,
            use: {
              loader: 'babel-loader',
              options: babelConfig(),
              // options: {
              //   presets: ['@umijs/babel-preset-umi/app'],
              //   plugins: [require('./scripts/replaceLib')],
              // },
            },
          },
          {
            test: /\.css$/,
            use: [
              {
                loader: 'style-loader', // creates style nodes from JS strings
              },
              {
                loader: 'css-loader', // translates CSS into CommonJS
              },
            ],
          },
          {
            test: /\.less$/,
            use: [
              {
                loader: MiniCssExtractPlugin.loader,
                options: {
                  publicPath: (resourcePath, context) =>
                    `${path.relative(path.dirname(resourcePath), context)}/`,
                },
              },
              {
                loader: 'css-loader', // translates CSS into CommonJS
              },
              {
                loader: 'less-loader',
                options: {
                  lessOptions: {
                    javascriptEnabled: true,
                  },
                },
              },
            ],
          },
        ],
      },
      externals: [
        {
          react: 'React',
          'react-dom': 'ReactDOM',
          antd: 'antd',
          moment: 'moment',
        },
        /^antd/,
      ],
      plugins: [
        new MiniCssExtractPlugin({
          // Options similar to the same options in webpackOptions.output
          // both options are optional
          filename: '[name].css',
          chunkFilename: '[id].css',
        }),
      ],
    },
  ];
}

const defaultConfig = webpackConfig();
const webpackPOPConfig = webpackConfig();
processWebpackThemeConfig(webpackPOPConfig, 'pop', popVars);

module.exports = [...defaultConfig, ...webpackPOPConfig];
